package de.jmda.gen.java;

import java.util.List;

import javax.validation.constraints.NotNull;

import de.jmda.gen.GeneratorException;

/**
 * Generator for content of <code>*.java</code> files other than <code>
 * package.java</code> (see {@link CompilationUnitPackageGenerator}. A package
 * statement (see {@link #getPackageStatementGenerator()}) and import statements
 * (see {@link #getImportStatementsGenerator()} and {@link
 * ImportStatementGenerator}) can be part of the content.
 * <p>
 * A typical compilation unit for types has one non nested top level type (see
 * {@link #getCompilationUnitTypeDeclarationGenerator()}). However it is
 * possible (though rarely used) to declare additional non nested types in a
 * compilation unit (see {@link #getTopLevelTypeDeclarationGenerators()}).
 *
 * @author rwegner
 */
public interface CompilationUnitTypeGenerator
		extends CompilationUnitGenerator
{
	PackageStatementGenerator getPackageStatementGenerator();
	void setPackageStatementGenerator(PackageStatementGenerator generator);
	/**
	 * @NotNull
	 * @return
	 */
	PackageStatementGenerator demandPackageStatementGenerator();

	ImportStatementsGenerator getImportStatementsGenerator();
	void setImportStatementsGenerator(ImportStatementsGenerator generator);
	/**
	 * @NotNull
	 * @return
	 */
	ImportStatementsGenerator demandImportStatementsGenerator();

	@NotNull TypeDeclarationGenerator getCompilationUnitTypeDeclarationGenerator();
	void setCompilationUnitTypeDeclarationGenerator(
			@NotNull TypeDeclarationGenerator generator);

	@NotNull
	List<TypeDeclarationGenerator> getTopLevelTypeDeclarationGenerators();
	void setTopLevelTypeDeclarationGenerators(
			@NotNull List<TypeDeclarationGenerator> generators);

	/**
   * convenience method for quick access to package name
   *
   * @return
   * @throws GeneratorException
   */
	String getPackageName() throws GeneratorException;

  /**
   * convenience method for quick access to package name
   * 
   * @param package name, if <code>null</code> no package statement will be
   *        generated
   */
  void setPackageName(String packagename);

  /**
   * convenience method for quick access to name of compilation unit type
   *
   * @return non <code>null</code> name of compilation unit type
   * @throws GeneratorException
   */
  @NotNull String getCompilationUnitTypeName() throws GeneratorException;

  /**
   * convenience method for quick access to name of compilation unit type
   *
   * @param name must not be <code>null</code>
   */
  void setCompilationUnitTypeName(@NotNull String name);
}